package bom.example.common.jsonfilter;

import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;
import org.springframework.http.HttpOutputMessage;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageNotWritableException;

import java.io.IOException;
import java.io.OutputStream;
import java.nio.charset.Charset;
import java.util.Arrays;

/**
 * @author Xiongx
 * @version 1.0
 * @date 2021/6/12 14:46
 * @since JDK 1.8
 */
public class JsonFilterHttpMessageConverter extends FastJsonHttpMessageConverter {

    private Charset charset;
    private SerializerFeature[] features;

    public JsonFilterHttpMessageConverter() {
        super();
        setSupportedMediaTypes(
                Arrays.asList(new MediaType("application", "json", Charset.forName("UTF8")), new MediaType("application", "*+json", Charset.forName("UTF8")),
                        new MediaType("application", "jsonp", Charset.forName("UTF8")), new MediaType("application", "*+jsonp", Charset.forName("UTF8"))));
        setCharset(Charset.forName("UTF8"));
        setFeatures(SerializerFeature.DisableCircularReferenceDetect, SerializerFeature.WriteMapNullValue);
    }

    /**
     *
     * @param obj-the object to write to the output message
     * @param outputMessage-the HTTP output message to write to
     * @throws IOException-in case of I/O errors
     * @throws HttpMessageNotWritableException -in case of conversion errors
     */
    @Override
    protected void writeInternal(Object obj, HttpOutputMessage outputMessage)
            throws IOException, HttpMessageNotWritableException {
        if (obj instanceof JsonFilterObject) {
            JsonFilterObject jsonFilterObject = (JsonFilterObject) obj;
            OutputStream out = outputMessage.getBody();
            SimpleSerializerFilter simpleSerializerFilter = new SimpleSerializerFilter(jsonFilterObject.getIncludes(),
                    jsonFilterObject.getExcludes());
            /**
             * JSON序列化接口toJSONString String toJSONString(Object, SerializeFilter, SerializerFeature...)
             */
            String text = JSONObject.toJSONString(jsonFilterObject.getJsonObject(), simpleSerializerFilter, features);
            byte[] bytes = text.getBytes(this.charset);
            out.write(bytes);
        } else {
            /**
             * 未声明@SerializeField注解
             */
            OutputStream out = outputMessage.getBody();
            String text = "";
            if (obj instanceof JSONObject) {
                JSONObject json = (JSONObject) obj;
                text = json.toJSONString();
            } else {
                text = JSONObject.toJSONString(obj, this.features);
            }
            byte[] bytes = text.getBytes(this.charset);
            out.write(bytes);
        }
    }

    @Override
    public void setCharset(Charset charset) {
        this.charset = charset;
    }

    @Override
    public void setFeatures(SerializerFeature... features) {
        this.features = features;
    }


}
